package com.alibaba.travel.member.Interceptor;

import com.alibaba.travel.common.constant.RedisConstants;
import com.alibaba.travel.common.utils.JwtUtil;
import com.alibaba.travel.member.Utils.UserHolder;
import com.alibaba.travel.member.entity.UserEntity;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.User;
import org.apache.commons.lang.StringUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.ObjectUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.concurrent.TimeUnit;


@Slf4j
public class RefreshInterceptor implements HandlerInterceptor {

    private ObjectMapper objectMapper;

    private StringRedisTemplate stringRedisTemplate;

    public RefreshInterceptor(StringRedisTemplate stringRedisTemplate, ObjectMapper objectMapper) {
        this.objectMapper=objectMapper;
        this.stringRedisTemplate=stringRedisTemplate;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //拦截所有请求，不做拦截，只做判断更新
        //所有请求头都需带有token令牌，令牌中存储用户信息id；
        String jwt = request.getHeader("token");
        if(StringUtils.isEmpty(jwt)){
            return true;
        }
        //有携带jwt
        Claims claims = JwtUtil.parseJWT(jwt);
        Long id = Long.valueOf(claims.getSubject());
        log.info("请求解析jwt得到的id={}",id);
        if(ObjectUtils.isEmpty(id)){
            return true;
        }
        //不为空，查询缓存中的user数据
        String jsonObject = stringRedisTemplate.opsForValue().get(RedisConstants.USER_LOGIN_KEY + id);
        if(StringUtils.isEmpty(jsonObject)){
            //过期放心。
            return true;
        }
        //不为空，解析成功，获取user信息,并且延长ttl
        stringRedisTemplate.expire(RedisConstants.USER_LOGIN_KEY + id,RedisConstants.USER_LOGIN_TTL, TimeUnit.HOURS);
        UserEntity userInfo = objectMapper.readValue(jsonObject, UserEntity.class);
        //存到上下文threadlocal中
        UserHolder.saveUser(userInfo);

        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        //一条请求结束，移除即可
        if(!ObjectUtils.isEmpty(UserHolder.getUser())){
            log.info("用户退出成功!{}",UserHolder.getUser().toString());
            UserHolder.removeUser();
        }
    }
}
